package com.zh.common.view

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.view.View
import com.zh.common.R
import com.zh.common.ktx.dp2px
import kotlin.math.min

/**
 * 圆形进度条带文字，水平进度不带文字
 */
class RoundProgressBar @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val paint by lazy { Paint().apply { isAntiAlias = true } }
    private var myProgress = 0// 0~100
    private var animator: ValueAnimator? = null
    private var radius = 0f//水平时的圆角
    private var color = 0//进度颜色
    private var bgColor = 0//背景颜色
    private var myStrokeWidth = 0f//圆形进度宽度
    private var textSize = 0f//文字大小
    private var isCir = true//是否是圆形
    private val textBounds by lazy { Rect() }

    init {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar)
        textSize =
            typedArray.getDimension(R.styleable.RoundProgressBar_rpb_text_size, 14f.dp2px.toFloat())
        radius =
            typedArray.getDimension(R.styleable.RoundProgressBar_rpb_radius, 3f.dp2px.toFloat())
        isCir = typedArray.getBoolean(R.styleable.RoundProgressBar_rpb_is_cir, true)
        color = typedArray.getColor(R.styleable.RoundProgressBar_rpb_color, Color.GREEN)
        bgColor = typedArray.getColor(R.styleable.RoundProgressBar_rpb_bg_color, Color.GRAY)
        myStrokeWidth = typedArray.getDimension(
            R.styleable.RoundProgressBar_rpb_width, 3f.dp2px.toFloat()
        )
        paint.textSize = textSize
        paint.strokeCap = Paint.Cap.ROUND
        paint.textAlign = Paint.Align.CENTER
        typedArray.recycle()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (isCir) {//圆形进度
            paint.strokeWidth = myStrokeWidth
            val space = paint.strokeWidth / 2
            paint.style = Paint.Style.STROKE
            canvas.save()
            paint.color = bgColor
            canvas.drawCircle(width / 2f, height / 2f, width / 2 - space, paint)
            canvas.restore()

            paint.color = color
            canvas.drawArc(
                space, space, width - space, height - space,
                270f, 360 * myProgress / 100f, false, paint
            )

            paint.strokeWidth = 0f
            paint.style = Paint.Style.FILL
            val content = "$myProgress%"
            paint.getTextBounds(content, 0, content.length, textBounds)
            val y = height / 2f + (textBounds.height() / 2f - textBounds.bottom)
            canvas.drawText(content, width / 2f, y, paint)
        } else {//水平进度
            val space = paint.strokeWidth / 2
            paint.style = Paint.Style.FILL
            canvas.save()
            paint.color = bgColor
            canvas.drawRoundRect(
                space, space, width - space, height - space,
                radius, radius, paint
            )
            canvas.restore()

            paint.color = color
            canvas.drawRoundRect(
                space, space, (width - space) / 100f * myProgress, height - space,
                radius, radius, paint
            )
        }
    }

    /**
     * 更新进度 0 ~ 100
     */
    fun updateProgress(progress: Int) {
        if (animator != null && animator?.isRunning == true) {
            animator?.cancel()
            animator = null
        }
        animator = ValueAnimator.ofInt(myProgress, min(progress, 100))
        animator?.apply {
            duration = 300
            addUpdateListener {
                myProgress = it.animatedValue as Int
                try {
                    invalidate()
                } catch (e: Exception) {
                    e.printStackTrace()
                    postInvalidate()
                    try {
                        postInvalidate()
                    } catch (e2: Exception) {
                        e2.printStackTrace()
                    }
                }
            }
            start()
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        animator?.cancel()
    }
}